package com.pay.ioopos.support.scan;

/**
 * IC卡发送指令工具类
 * @author Moyq5
 * @date 2020年1月15日
 */
public abstract class IcSendCmdUtils {

    /**
     * 读卡号指令
     * @author Moyq5
     * @date 2020年1月15日
     *
     * @return 读卡指令数据包
     */
    public static byte[] find() {
        byte[] data = new byte[6];
        data[0] = 0x00;
        data[1] = 0x00;
        data[2] = 0x03;
        data[3] = 0x03;
        data[4] = 0x00;

        return sign(data);
    }

    /**
     * 钱包初始化指令
     * @author Moyq5
     * @date 2020年1月15日
     *
     * @param wallet 钱包号，即块号
     * @param keyType 密钥类型
     * @param key 密钥
     * @param amount 初始余额
     * @return 初始化指令数据包
     */
    public static byte[] initWallet(int wallet, IcKeyType keyType, String key, int amount) {
        byte[] data = new byte[17];
        data[0] = 0x00;
        data[1] = 0x00;
        data[2] = 0x0E;
        data[3] = 0x06;
        data[4] = (byte)keyType.ordinal();
        data[5] = (byte)wallet;

        byte[] keyBytes = key.getBytes();
        for (int i = 0; i < 6; i++) {
            if (i < keyBytes.length) {
                data[6+i] = keyBytes[i];
            } else {
                data[6+i] = 0x00;
            }
        }

        data[12] = (byte)(amount & 0xFF);
        data[13] = (byte)((amount & 0xFF00) >> 8);
        data[14] = (byte)((amount & 0xFF0000) >> 16);
        data[15] = (byte)((amount & 0xFF000000) >> 32);

        return sign(data);
    }

    /**
     *
     * 钱包充值指令
     * @author Moyq5
     * @date 2020年1月15日
     *
     * @param wallet 钱包号，即块号
     * @param keyType 密钥类型
     * @param key 密钥
     * @param amount 充值金额，分
     * @return 充值指令数据包
     */
    public static byte[] chargeWallet(int wallet, IcKeyType keyType, String key, int amount) {
        byte[] data = new byte[17];
        data[0] = 0x00;
        data[1] = 0x00;
        data[2] = 0x0E;
        data[3] = 0x08;
        data[4] = (byte)keyType.ordinal();
        data[5] = (byte)wallet;

        byte[] keyBytes = key.getBytes();
        for (int i = 0; i < 6; i++) {
            if (i < keyBytes.length) {
                data[6+i] = keyBytes[i];
            } else {
                data[6+i] = 0x00;
            }
        }

        data[12] = (byte)(amount & 0xFF);
        data[13] = (byte)((amount & 0xFF00) >> 8);
        data[14] = (byte)((amount & 0xFF0000) >> 16);
        data[15] = (byte)((amount & 0xFF000000) >> 32);

        return sign(data);
    }

    /**
     *
     * 钱包扣款指令
     * @author Moyq5
     * @date 2020年1月15日
     *
     * @param wallet 钱包号，即块号
     * @param keyType 密钥类型
     * @param key 密钥
     * @param amount 扣款金额，分
     * @return 扣款指令数据包
     */
    public static byte[] expenseWallet(int wallet, IcKeyType keyType, String key, int amount) {
        byte[] data = new byte[17];
        data[0] = 0x00;
        data[1] = 0x00;
        data[2] = 0x0E;
        data[3] = 0x09;
        data[4] = (byte)keyType.ordinal();
        data[5] = (byte)wallet;

        byte[] keyBytes = key.getBytes();
        for (int i = 0; i < 6; i++) {
            if (i < keyBytes.length) {
                data[6+i] = keyBytes[i];
            } else {
                data[6+i] = 0x00;
            }
        }

        data[12] = (byte)(amount & 0xFF);
        data[13] = (byte)((amount & 0xFF00) >> 8);
        data[14] = (byte)((amount & 0xFF0000) >> 16);
        data[15] = (byte)((amount & 0xFF000000) >> 32);

        return sign(data);
    }

    /**
     *
     * 钱包读取指令
     * @author Moyq5
     * @date 2020年1月15日
     *
     * @param wallet 钱包号，即块号
     * @param keyType 密钥类型
     * @param key 密钥
     * @return 读取指令数据包
     */
    public static byte[] readWallet(int wallet, IcKeyType keyType, String key) {
        byte[] data = new byte[13];
        data[0] = 0x00;
        data[1] = 0x00;
        data[2] = 0x0A;
        data[3] = 0x07;
        data[4] = (byte)keyType.ordinal();
        data[5] = (byte)wallet;

        byte[] keyBytes = key.getBytes();
        for (int i = 0; i < 6; i++) {
            if (i < keyBytes.length) {
                data[6+i] = keyBytes[i];
            } else {
                data[6+i] = 0x00;
            }
        }

        return sign(data);
    }

    /**
     *
     * 钱包备份指令，前钱包块号密钥和备份钱包块号密钥要相同
     * @author Moyq5
     * @date 2020年1月15日

     * @param keyType 密钥类型
     * @param key 密钥
     * @param fromWallet 当前钱包号，即块号
     * @param toWallet 备份钱包号，即块号
     * @return 备份指令数据包
     */
    public static byte[] backupWallet(IcKeyType keyType, String key, int fromWallet, int toWallet) {
        byte[] data = new byte[14];
        data[0] = 0x00;
        data[1] = 0x00;
        data[2] = 0x0B;
        data[3] = 0x0A;
        data[4] = (byte)keyType.ordinal();
        data[5] = (byte)fromWallet;
        data[6] = (byte)toWallet;

        byte[] keyBytes = key.getBytes();
        for (int i = 0; i < 6; i++) {
            if (i < keyBytes.length) {
                data[6+i] = keyBytes[i];
            } else {
                data[6+i] = 0x00;
            }
        }

        return sign(data);
    }

    /**
     * 钱包休眠指令
     * @author Moyq5
     * @date 2020年1月15日

     * @return 休眠指令数据包
     */
    public static byte[] sleepWallet() {
        return new byte[]{0x00, 0x00, 0x02, 0x0B, 0x09};
    }

    /**
     * 校验值计算
     * @param data 未校验数据
     * @return 已校验数据
     */
    private static byte[] sign(byte[] data) {
        int index = data.length - 1;
        for (int i = 2; i < index; i++) {
            data[index] ^= data[i];
        }
        return data;
    }
}
